home *** CD-ROM | disk | FTP | other *** search
- /*
- * geometry.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * GEOMETRY.C
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "vor.h"
-
- #define ZERO 0.0
-
-
- void
- geominit ()
- {
- float sn;
-
- freeinit (&efl, sizeof (struct Edge));
-
- nedges = nvertices = 0;
- sn = (float) (nsites + 4); /* significance of const. 4 ?? */
- sqrt_nsites = 1 + (int) sqrt (sn); /* sqrt returns double !! */
-
- deltay = ymax - ymin;
- deltax = xmax - xmin;
- }
-
-
- struct Edge *
- bisect (s1, s2, imgIO, value)
- struct Site *s1, *s2;
- Image *imgIO;
- int value;
- {
- double dx, dy, adx, ady;
- struct Edge *newedge;
-
- newedge = (struct Edge *) getfree (&efl);
-
- newedge->reg[0] = s1;
- newedge->reg[1] = s2;
- ref (s1);
- ref (s2);
- newedge->ep[0] = (struct Site *) NULL;
- newedge->ep[1] = (struct Site *) NULL;
-
- dx = s2->coord.x - s1->coord.x;
- dy = s2->coord.y - s1->coord.y;
- if ((-1.0e-10 < dx) && (dx < 1.0e-10))
- dx = ZERO; /* vert */
- if ((-1.0e-10 < dy) && (dy < 1.0e-10))
- dy = ZERO; /* hor */
- adx = dx > 0 ? dx : -dx;
- ady = dy > 0 ? dy : -dy;
- newedge->c = (float) (dx * s1->coord.x + dy * s1->coord.y + (dx * dx + dy * dy) * 0.5);
-
- if (adx > ady) { /* covers case dy = 0.0 */
- newedge->a = (float) 1.0;
- newedge->b = (float) (dy / dx);
- newedge->c /= (float) dx;
- }
- else { /* covers case dx = 0.0 */
- newedge->b = (float) 1.0;
- newedge->a = (float) (dx / dy);
- newedge->c /= (float) dy;
- }
-
- newedge->edgenbr = nedges;
- out_bisector (newedge, imgIO, value);
- nedges += 1;
-
- return (newedge);
- }
-
-
- struct Site *
- intersect (el1, el2)
- struct Halfedge *el1, *el2;
- {
- struct Edge *e1, *e2, *e;
- struct Halfedge *el;
- float d, xint, yint;
- int right_of_site;
- struct Site *v;
-
- e1 = el1->ELedge;
- e2 = el2->ELedge;
- if ((e1 == (struct Edge *) NULL) || (e2 == (struct Edge *) NULL))
- return ((struct Site *) NULL);
- if (e1->reg[1] == e2->reg[1])
- return ((struct Site *) NULL);
-
- d = e1->a * e2->b - e1->b * e2->a;
- if ((-1.0e-10 < d) && (d < 1.0e-10))
- return ((struct Site *) NULL);
-
- xint = (e1->c * e2->b - e2->c * e1->b) / d;
- yint = (e2->c * e1->a - e1->c * e2->a) / d;
-
- if ((e1->reg[1]->coord.y < e2->reg[1]->coord.y) ||
- (e1->reg[1]->coord.y == e2->reg[1]->coord.y &&
- e1->reg[1]->coord.x < e2->reg[1]->coord.x)) {
- el = el1;
- e = e1;
- }
- else {
- el = el2;
- e = e2;
- }
-
- right_of_site = xint >= e->reg[1]->coord.x; /* Boolean */
- if ((right_of_site && el->ELpm == le) ||
- (!right_of_site && el->ELpm == re))
- return ((struct Site *) NULL);
-
- v = (struct Site *) getfree (&sfl);
- v->refcnt = 0;
- v->coord.x = xint;
- v->coord.y = yint;
-
- return (v);
- }
-
- /* returns 1 if p is to right of halfedge e */
- int
- right_of (el, p)
- struct Halfedge *el;
- struct Point *p;
- {
- struct Edge *e;
- struct Site *topsite;
- int right_of_site, above, fast;
- float dxp, dyp, dxs, t1, t2, t3, yl;
-
- e = el->ELedge;
- topsite = e->reg[1];
- right_of_site = p->x > topsite->coord.x;
- if (right_of_site && (el->ELpm == le))
- return (1);
- if (!right_of_site && (el->ELpm == re))
- return (0);
-
- if (e->a == 1.0) {
- dyp = p->y - topsite->coord.y;
- dxp = p->x - topsite->coord.x;
- fast = 0;
- if ((!right_of_site & e->b < 0.0) | (right_of_site & e->b >= 0.0)) {
- above = dyp >= e->b * dxp;
- fast = above;
- }
- else {
- above = p->x + p->y * e->b > e->c;
- if (e->b < 0.0)
- above = !above;
- if (!above)
- fast = 1;
- }
-
- if (!fast) {
- dxs = topsite->coord.x - (e->reg[0])->coord.x;
- above = e->b * (dxp * dxp - dyp * dyp) <
- dxs * dyp * (1.0 + 2.0 * dxp / dxs + e->b * e->b);
- if (e->b < 0.0)
- above = !above;
- }
- }
- else { /*e->b==1.0 */
- yl = e->c - e->a * p->x;
- t1 = p->y - yl;
- t2 = p->x - topsite->coord.x;
- t3 = yl - topsite->coord.y;
- above = t1 * t1 > t2 * t2 + t3 * t3;
- }
-
- return (el->ELpm == le ? above : !above);
- }
-
-
- void
- endpoint (e, lr, s, imgIO, value)
- struct Edge *e;
- int lr;
- struct Site *s;
- Image *imgIO;
- int value;
- {
- e->ep[lr] = s;
- ref (s);
-
- if (e->ep[re - lr] == (struct Site *) NULL)
- return;
-
- out_ep (e, imgIO, value);
- deref (e->reg[le]);
- deref (e->reg[re]);
- makefree ((struct Freenode *) e, &efl); /* diff. types, parm 1 !! */
- }
-
-
- float
- dist (s, t)
- struct Site *s, *t;
- {
- float dx, dy;
-
- dx = s->coord.x - t->coord.x;
- dy = s->coord.y - t->coord.y;
-
- return ((float) sqrt (dx * dx + dy * dy));
- }
-
-
- void
- makevertex (v) /* S. Fortune orig. routine: type int */
- struct Site *v;
- {
- v->sitenbr = nvertices;
- nvertices += 1;
- out_vertex (v);
- }
-
-
- void
- deref (v)
- struct Site *v;
- {
- v->refcnt -= 1;
- if (v->refcnt == 0)
- makefree ((struct Freenode *) v, &sfl);
- }
-
- void
- ref (v)
- struct Site *v;
- {
- v->refcnt += 1;
- }
-